import platform from '@/common/platform'
// #ifdef H5
import $wxsdk from '@/common/libs/sdk-h5-weixin'
// #endif
import { prePayment } from '@/api/payment'
import Helper from '@/common/helper'
import ROUTE from '@/router'

/**
 * 支付
 *
 * @param {String} payment = ['wechat','alipay','wallet','offline']  	- 支付方式
 * @param {String} scene = ['reserve','bill','recharge']  	- 订单类型: 预定 | 账单 | 充值
 * @param {Object} parmas = {}  	- 订单请求参数
 * @param {String} outTradeNo					- 订单交易单号
 * @param {String} payState	= ['success','fail'] 				- 支付结果
 */

export default class Payment {
  constructor(payment, scene, parmas) {
    this.payment = payment
    this.outTradeNo = ''
    this.scene = scene
    this.arguments = parmas
    return new Promise(async (resolve, reject) => {
      resolve(await this.payAction())
    })
  }

  async payAction() {
    return new Promise(async (resolve, reject) => {
      const payAction = {
        WechatOfficialAccount: {
          wechat: () => {
            this.wechatOfficialAccountPay()
          },
          alipay: () => {
            this.redirectPay() // 现在公众号可以直接跳转支付宝页面
          },
          money: () => {
            this.moneyPay()
          },
          offline: () => {
            this.offlinePay()
          },
        },
        WechatMiniProgram: {
          wechat: async () => {
            await this.wechatMiniProgramPay()
          },
          alipay: () => {
            this.copyPayLink()
          },
          money: () => {
            this.moneyPay()
          },
          offline: () => {
            this.offlinePay()
          },
        },
        App: {
          wechat: () => {
            this.wechatAppPay()
          },
          alipay: () => {
            this.alipay()
          },
          money: () => {
            this.moneyPay()
          },
          offline: () => {
            this.offlinePay()
          },
        },
        H5: {
          wechat: () => {
            this.wechatWapPay()
          },
          alipay: () => {
            this.redirectPay()
          },
          money: () => {
            this.moneyPay()
          },
          offline: () => {
            this.offlinePay()
          },
        },
      }
      resolve(await payAction[platform.name][this.payment]())
    })
  }

  // 预支付
  async prepay() {
    // #ifdef MP
    const { session_key } = await platform.useProvider().getSessionId()
    // #endif
    const params = {
      scene: this.scene,
      arguments: { ...this.arguments },
      // #ifdef MP
      sessionKey: session_key,
      // #endif
    }
    return await prePayment(params)
  }
  // #ifdef H5
  // 微信公众号JSSDK支付
  async wechatOfficialAccountPay() {
    const that = this
    const { errcode, data, msg } = await this.prepay()
    if (errcode !== 0) {
      console.log('支付错误', msg)
      return
    }
    $wxsdk.wxpay(data.pay_data, {
      success: () => {
        that.payResult('success')
      },
      cancel: () => {
        uni.$uv.toast('支付已手动取消')
      },
      fail: () => {
        that.payResult('fail')
      },
    })
  }

  //浏览器微信H5支付
  async wechatWapPay() {
    const { errcode, data } = await this.prepay()
    if (errcode === 0) {
      const paramStr = uni.$uv.queryParams(this.arguments)
      const redirect_url = `${Helper.getRootUrl()}pages/payment/result${paramStr ? `${paramStr}&` : '?'}outTradeNo=${this.outTradeNo}&payment=${this.payment}&scene=${this.scene}`
      location.href = `${data.pay_data.h5_url}&redirect_url=${encodeURIComponent(redirect_url)}`
    }
  }

  // 支付链接
  async redirectPay() {
    const { errcode, data } = await this.prepay()
    if (errcode === 0) {
      const paramStr = uni.$uv.queryParams(this.arguments)
      const redirect_url = `${Helper.getRootUrl()}pages/payment/result${paramStr ? `${paramStr}&` : '?'}outTradeNo=${this.outTradeNo}&payment=${this.payment}&scene=${this.scene}`
      location.href = data.pay_data + encodeURIComponent(redirect_url)
    }
  }

  // #endif

  // 微信小程序支付
  async wechatMiniProgramPay() {
    return new Promise(async (resolve, reject) => {
      const that = this
      const { errcode, data } = await this.prepay()
      if (errcode === 0) {
        this.outTradeNo = data.outTradeNo
        uni.requestPayment({
          provider: 'wxpay',
          ...data.jsApiParameters,
          success: (res) => {
            that.payResult('success')
            resolve(res)
          },
          fail: (err) => {
            if (err.errMsg === 'requestPayment:fail cancel') {
              uni.$uv.toast('支付已手动取消')
            } else {
              that.payResult('fail')
            }
            resolve(err)
          },
        })
      } else {
        resolve()
      }
    })
  }

  // 余额支付
  async moneyPay() {
    const { errcode } = await this.prepay()
    errcode === 0 && this.payResult('success')
  }

  // 货到付款
  async offlinePay() {
    const { errcode } = await this.prepay()
    errcode === 0 && this.payResult('success')
  }

  // 支付宝复制链接支付
  async copyPayLink() {
    const that = this
    const { errcode, data } = await this.prepay()
    if (errcode === 0) {
      // 引入showModal 点击确认 复制链接；
      uni.showModal({
        title: '支付宝支付',
        content: '复制链接到外部浏览器',
        confirmText: '复制链接',
        success: (res) => {
          if (res.confirm) {
            Helper.copyText(data.pay_data)
          }
        },
      })
    }
  }

  // 支付宝支付
  async alipay() {
    const that = this
    const { errcode, data } = await this.prepay()
    if (errcode === 0) {
      uni.requestPayment({
        provider: 'alipay',
        orderInfo: data.pay_data, //支付宝订单数据
        success: (res) => {
          that.payResult('success')
        },
        fail: (err) => {
          if (err.errMsg === 'requestPayment:fail [paymentAlipay:62001]user cancel') {
            uni.$uv.toast('支付已手动取消')
          } else {
            that.payResult('fail')
          }
        },
      })
    }
  }

  // 微信支付
  async wechatAppPay() {
    const that = this
    const { errcode, data } = await this.prepay()
    if (errcode === 0) {
      uni.requestPayment({
        provider: 'wxpay',
        orderInfo: data.pay_data, //微信订单数据(官方说是string。实测为object)
        success: (res) => {
          that.payResult('success')
        },
        fail: (err) => {
          err.errMsg !== 'requestPayment:fail cancel' && that.payResult('fail')
        },
      })
    }
  }

  // 支付结果跳转,success:成功，fail:失败
  payResult(resultType) {
    ROUTE.redirect('/pages/payment/result', {
      outTradeNo: this.outTradeNo, // 查询订单支付结果使用
      payment: this.payment, //重新支付的时候使用
      payState: resultType, // 前端支付结果判断
      ...this.arguments, //
    })
  }
}
